<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8">
        <title>操作节点</title>
        <style>
            .buttons { border: 1px solid blue; margin: 15px auto; }
            .buttons>button { margin: 10px 0 10px 10px; }

            .wrapper { border: 1px solid green; margin: 15px auto; }
            .wrapper>header,
            .wrapper>footer { border: 1px solid gray; margin: 10px; background: #dfdfdf; }
            .target { border: 1px solid red; margin: 10px; }
            .target p { margin: 0; }
            .target>*:nth-child(2n) { background: #f4f4f4; }
            .target>*:nth-child(2n+1) { background: #ffff00; }
        </style>
    </head>
    <body>
        <h1>操作节点</h1>

        <div class="buttons">
            <button type="button" class="find">父子兄弟</button>
            <button type="button" class="append">追加元素</button>
            <button type="button" class="insert">插入元素</button>
            <button type="button" class="replace">替换元素</button>
            <button type="button" class="remove">删除元素</button>
            <button type="button" class="deep-clone">深克隆</button>
            <button type="button" class="shallow-clone">浅克隆</button>
        </div>

        <div class="wrapper">
            <header>大老大</header>
            <div class="target">
                <div>小老大</div>
                <p>我是个段落</p>
                <div><p>小老幺</p></div>
            </div>
            <footer>大老幺</footer>
        </div>

        <div class="wrapper">
            <p>Node的原型属性</p>
            <ul>
                <li>Node.prototype.appendChild( newNode ) 在节点内部末尾追加新节点</li>
                <li>Node.prototype.insertBefore( newNode, refNode ) 在节点内部指定子节点前插入新节点</li>
                <li>Node.prototype.replaceChild( newNode, oldNode ) 用新节点替换当前节点内指定子节点</li>
                <li>Node.prototype.removeChild( child ) 删除当前节点内指定子节点</li>
                <li>Node.prototype.cloneNode( deep ) 克隆当前节点</li>
            </ul>
        </div>

        <div class="wrapper">
            <p>Element的原型属性</p>
            <ul>
                <li>Element.prototype.querySelector( selector ) 选择元素内部符合给定选择器的首个元素</li>
                <li>Element.prototype.querySelectorAll( selector ) 选择元素内部符合给定选择器的所有元素</li>
                <li>Element.prototype.append( element ) 在元素内部末尾追加新的子元素</li>
            </ul>
        </div>

        <div class="wrapper">
            <p>Document的原型属性</p>
            <ul>
                <li>Document.prototype.createElement( standardHtmlTagName ) 根据标准HTML标签名创建新元素</li>
            </ul>
        </div>

        <script>
            // 定义一个用于为元素绑定点击事件监听器的函数
            function bind(element, handler){
                element.addEventListener('click', handler, false);
            }

            // 寻找匹配于指定选择器的首个元素
            const findBtn = document.querySelector('.buttons>.find');
            // 绑定点击事件对应的处理程序(此处的处理程序是个函数)
            bind(findBtn, function(){
                const t = document.querySelector('.target');
                // 获取父元素
                let parent = t.parentElement;
                console.log( parent );
                // 获取兄弟元素
                let prev = t.previousElementSibling;
                console.log( prev );
                let next = t.nextElementSibling;
                console.log( next );
                console.log( t );
                // 取得子元素数
                let count = t.childElementCount;
                if( count > 0 ) {
                    // 获取子元素
                    Array.from(t.children).forEach( e => console.log('\t', e) );
                    console.log('\t', '- '.repeat(10));
                    // 获取指定元素内符合指定选择器的所有元素
                    let ps = t.querySelectorAll('p'); // Element.prototype.querySelectorAll( selector )
                    console.log( '\t', ps );
                    let divs = t.querySelectorAll('div'); 
                    console.log( '\t', divs );
                }
            });
            
            const appendBtn = document.querySelector('.buttons>.append');
            bind(appendBtn, function(){
                const t = document.querySelector('.target');
                // 创建新元素
                let x = document.createElement('div');
                // 通过 innerHTML 属性为 新元素 设置文本内容
                x.innerHTML = Date.now();

                // 调用从 Node.prototype 继承的方法在当前节点内部末尾追加子节点
                // t.appendChild( x ); // Node.prototype.appendChild( node )

                // 调用从 Element.prototype 继承的方法在当前元素内部末尾追加子元素
                t.append(x); // Element.prototype.append( element )
            });

            const insertBtn = document.querySelector('.buttons>.insert');
            bind(insertBtn, function(){
                const parent = document.querySelector('.target');
                let refNode = parent.querySelector('p');
                let newNode = document.createElement('div');
                newNode.innerHTML = new Date().toISOString();
                // 在 parent 内部的 refNode 之前插入 newNdoe
                parent.insertBefore(newNode, refNode); // Node.prototype.insertBefore(n,r)
            });

            const replaceBtn = document.querySelector('.buttons>.replace');
            bind(replaceBtn, function(){
                const t = document.querySelector('.target');
                let refNode = t.querySelector('p');
                if(refNode){
                    let newNode = document.createElement('p');
                    newNode.innerHTML = new Date().toISOString();
                    t.replaceChild(newNode, refNode); // Node.prototype.replaceChild(n,r)
                }
            });

            const removeBtn = document.querySelector('.buttons>.remove');
            bind(removeBtn, function(){
                const t = document.querySelector('.target');
                let child = t.lastElementChild;
                if( child ) {
                    t.removeChild(child); // Node.prototype.removeChild(child)
                }
            });

            const deepCloneBtn = document.querySelector('.buttons>.deep-clone');
            bind(deepCloneBtn, function(){
                // 获得被克隆的目标元素
                const t = document.querySelector('.target');
                // 获得被克隆元素的父元素
                const p = t.parentNode;
                // 深克隆目标元素
                const n = t.cloneNode(true);
                // 将克隆后得到的新元素追加到 被克隆元素父元素内部末尾
                p.appendChild(n);
            });
        </script>
    </body>
</html>

